(function($){
	var KEY = "jforest.tree",NODE_KEY="jforest.tree.node";
	
	var TreeNode = function(options){
		this.options = $.extend({
			isLast:true,
			isLeaf:true,
			isRoot:false,
			switchClick:function(){},
			nodeClick:function(){}
		},options);
	}

	TreeNode.prototype = {
		createEl:function(){
			var opts = this.options,node = this;
			this.$el = $('<li></li>');
			this.$el.append(this.switchEl());
			this.$el.append(this.infoEl());
			this.$el.data(NODE_KEY,this);
			return this.$el;
		},
		//节点信息
		infoEl:function(){
			var my=this,opts=this.options;
			var $a=$('<a href="javascript:void(0);"><i class="fa"></i>'+opts.name+'</a>');
			if(opts.isLeaf==false){
				$a.find('>i').addClass('fa-folder');
			}else{
				$a.find('>i').addClass('fa-file');
			}
			$a.click(function(){
				opts.nodeClick.apply(my);
			})
			return $a;
		},
		//节点的展开缩回开关
		switchEl:function(){
			var opts=this.options,node=this;
			if(opts.isRoot==true){
				return $('<span class="button root-close"></span>').click(function(){
					opts.switchClick.apply(node);
				});
			}else if(opts.isLeaf==false){ //如果不是叶子节点
				var $span = $('<span class="button"></span>');
				if(opts.isLast==true){//如果是最后一个节点
					$span.addClass('bottom-close');
				}else{
					$span.addClass('center-close');
				}
				$span.click(function(){
					opts.switchClick.apply(node);
				})
				return $span;
			}else if(opts.isLast==true){
				return $('<span class="button bottom-line"></span>');
			}else{
				return $('<span class="button center-line"></span>');
			}
		},
		createChildEl:function(){
			if(this.$el.find('>ul').length==0){
				if(this.options.isLast==false){
					this.$el.append('<ul class="line" style="display:none;"></ul>');
				}else{
					this.$el.append('<ul style="display:none;"></ul>');
				}
			}
			return this.$el.find('>ul');
		},
		_toggle:function(spanEl,openClass,closeClass){
			var opts = this.options,node = this;
			if($(spanEl).hasClass(closeClass)){
				$(spanEl).removeClass(closeClass);
				$(spanEl).addClass(openClass);
				if(node.$el.find('>ul').length==1){
					node.$el.find('>ul').show(300);
				}else{
					opts.loadData.apply(node,[function(){
						node.$el.find('>ul').show(300);
					}]);
				}
			}else{
				$(spanEl).removeClass(openClass);
				$(spanEl).addClass(closeClass);
				node.$el.find('>ul').hide(300);
			}
		},
		hasChild:function(){
			return this.$el.find('>ul>li').length>0;
		},
		isOpen:function(){
			return this.$el.find('>span').hasClass('root-open')||this.$el.find('>span').hasClass('center-open') 
				||this.$el.find('>span').hasClass('bottom-open');
		},
		close:function(){
			var $spanEl=this.$el.find('>span:first'),opts = this.options;
			this.$el.find('>ul').hide(300);
			if(opts.isLeaf == false){
				if(opts.isRoot==true){
					jf.replaceClass($spanEl,'root-open','root-close');
				}else if(opts.isLast==true){
					jf.replaceClass($spanEl,'bottom-open','bottom-close');
				}else{
					jf.replaceClass($spanEl,'center-open','center-close');
				}
			}
		},
		open:function(){
			var $spanEl=this.$el.find('>span:first'),opts=this.options;
			this.$el.find('>ul').show(300);
			if(opts.isLeaf == false){
				if(opts.isRoot==true){
					$spanEl.removeClass('root-close');
					$spanEl.addClass('root-open');
				}else if(opts.isLast==true){
					$spanEl.removeClass('bottom-close');
					$spanEl.addClass('bottom-open');
				}else{
					$spanEl.removeClass('center-close');
					$spanEl.addClass('center-open');
				}
			}
		},
		refresh:function(){
			this.close();
			this.$el.find('>ul').empty();
		}
	}
	
	
	var Tree = function(element,options){
		this.$el = $(element);
		this.options = $.extend({
			ajax:undefined,
			checkbox:false,
			autoLoad:false,
			nodeClick:function(node){},
			checkboxClick:function(node){},
			root:{id:null,name:'根节点'}
		},options);
		//定义AJAX
		if(this.options.ajax){
			this.ajax = jf.getAjax({
				bindObj:this,
				url:this.options.ajax.url,
				param:$.isFunction(this.options.ajax.param)?{}:this.options.ajax.param
			});
		}
		//初始化
		this._initial();
		this._switchClick(this.root);
	};

	Tree.prototype = {
		_initial:function(){
			var my=this,opts=this.options;
			var $tree = $('<ul class="jf-tree"></ul>').appendTo(this.$el);
			//创建根节点
			this.root = this._addNode(null,$tree,{
				id:opts.root.id,
				name:opts.root.name,
				checked:opts.root.checked,
				isRoot:true,
				isLeaf:false,
				switchClick:function(){my._switchClick(this);},
				nodeClick:function(){opts.nodeClick.apply(my,[this]);}
			});
			this._addChildNode(this.root,opts.root.children);
		},
		_addNode:function(pnode,$childEl,options){
			var opts=this.options,my=this;
			var node = new TreeNode(options);
			if(opts.checkbox==true){ //如果待复选框
				node = new CheckboxPlug(node,{
					checkboxChange:opts.checkboxClick
				});
			}
			$childEl.append(node.createEl(pnode));
			return node;
		},
		_addChildNode:function(node,children){
			var opts=this.options,my=this;
			if($.isArray(children)){
				var $childEl = node.createChildEl();
				$.each(children,function(i,v){
					var childNode = my._addNode(node,$childEl,$.extend(v,{
						switchClick:function(){my._switchClick(this);},
						nodeClick:function(){opts.nodeClick.apply(my,[this]);},
						isLeaf:jf.isNotNull(v.isLeaf)?v.isLeaf:$.isArray(v.children)==false,
						isLast:i==(children.length-1)
					}));
					if(childNode.options.isLeaf==false){
						my._addChildNode(childNode,v.children);
						if(opts.autoLoad == true){
							my._switchClick(childNode);
						}
					}
				})
			}
		},
		_switchClick:function(node){
			var nOpts=node.options,opts=this.options,my=this;
			if(node.isOpen()){
				node.close();
			}else if(!node.hasChild() && this.ajax){
				var param = {pid:nOpts.id};
				if($.isFunction(opts.ajax.param)){
					param = opts.ajax.param.apply(node);
				}
				this.ajax.load(param,function(result){
					if($.isFunction(opts.ajax.callback)){
						result = opts.ajax.callback.apply(node,[result]);
					}
					my._addChildNode(node,result);
					node.open();
				});
			}else{
				node.open();
			}
		},
		refresh:function(){
			this.root.refresh();
		},
		getRoot:function(){
			return this.root;
		}
	};
	
	$.fn.jfTree = function(){
		var args = Array.prototype.slice.call(arguments, 0);
		var value = undefined;
		this.each(function () {
			var $this = $(this);
			if (args.length === 0 || typeof(args[0]) === "object") {
				opts = args.length === 0 ? {} : $.extend({}, args[0]);
				$this.data(KEY,new Tree(this,opts)); //创建控件
			}else if (typeof(args[0]) === "string"){
				var entity = $this.data(KEY);
                if(entity === undefined){return;}
                value = entity[args[0]].apply(entity, args.slice(1));
			}else{
				 throw 'Invalid arguments to '+KEY+' plugin: ' + args;
			}
	    });
	    return (value === undefined) ? this : value;
	};
	
	$.fn.jfTree.Constructor = Tree;
	
	var CheckboxPlug = function(node,options){
		$.extend(this,node,{
			createEl:function(pnode){
				this.$el = $('<li></li>');
				this.$el.append(this.switchEl());
				this.$el.append(this.checkboxEl(pnode));
				this.$el.append(this.infoEl());
				this.$el.data(NODE_KEY,this);
				return this.$el;
			},
			checkboxEl:function(pnode){
				var opts=this.options,my=this;
				var $span = $('<span class="checkbox"></span>');
				$span.click(function(){my.checkboxClick.apply(my,[this]);});
				if(pnode && pnode.options.checked == false){
					if(opts.checked == true){
						opts.checked = false;
						$span.addClass('cb4');
					}else{
						$span.addClass('cb3');
					}
				}else{
					if(opts.checked){$span.addClass('cb2');}else{$span.addClass('cb1');}
				}
				return $span;
			},
			checkboxClick:function(cbEl){
				var opts=this.options,my=this;
				if($(cbEl).hasClass('cb1') || $(cbEl).hasClass('cb2')){
					var checked = !opts.checked;
					opts.checkboxChange.apply(my,[cbEl,checked]);
					this.value(checked);
				}
			},
			value:function(val,flag){
				this.options.checked = val;
				var $cbEl = this.$el.find('>.checkbox');
				if(flag == true && ($cbEl.hasClass('cb3') || $cbEl.hasClass('cb4'))){
					if(val == true){
						$cbEl.removeClass('cb4');
						$cbEl.removeClass('cb3');
						$cbEl.addClass('cb2');
					}else{
						$cbEl.removeClass('cb4');
						$cbEl.removeClass('cb3');
						$cbEl.addClass('cb1');
					}
				}else if(flag == false){
					jf.replaceClass($cbEl,'cb1','cb3');
					jf.replaceClass($cbEl,'cb2','cb3');
				}else{
					jf.toggleClass($cbEl,'cb1','cb2');
				}
				this.chlidren(val);
			},
			chlidren:function(flag){
				this.$el.find('>ul>li').each(function(i,el){
					var node = $(el).data(NODE_KEY);
					node.value(false,flag);
				});
			},
			getCheckedIds:function(){
				var val = '';
				this.$el.find('>ul li').each(function(i,el){
					var node = $(el).data(NODE_KEY);
					if(node.options.checked==true){val = val+","+node.options.id;}
				});
				return val.substring(1);
			},
			getChildrenIds:function(){
				var val = '';
				this.$el.find('>ul input[type="checkbox"]').each(function(i,el){
					val = val+","+$(el).val();
				});
				return val.substring(1);
			}
		});
		this.options=$.extend(this.options,{
			checkboxChange:function(cbEl){}
		},options);
	}
})(window.jQuery)